#include "precompile.h"

#include "Document.h"
#include "View.h"
#include "Workspace.h"
#include "document/Types.h"
#include "Controller.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

Document::Document()
	:m_workspace(NULL),
	m_root(NULL)
{
}

Document::~Document()
{
}

vresult Document::New(const String& name,
					  Workspace* workspace,
					  documentCategory category,
					  pageTypesetCategory pageTypeset,
					  pageBindingCategory pageBinding,
					  uint32 pageCount,
					  real pageHeight,
					  real pageWidth,
					  real pageLeftMargin,
					  real pageTopMargin,
					  real pageRightMargin,
					  real pageBottonMargin)
{
	m_connection.CreateObject(CLSID_Connection);
	m_name = name;
	m_workspace = workspace;

	if (Opening())
		Opening()(sys::getSelf<IDocument>(this),name);

	sys::ServiceInterfacePtr<IBuildService> pIFBuildService(BUILD_SERVICE);
	if (!pIFBuildService)
		return vfailed;
	IObject* root = pIFBuildService->BuildDocument(GetConnection(),category,pageTypeset,pageBinding,pageCount,pageHeight,pageWidth,pageLeftMargin,pageTopMargin,pageRightMargin,pageBottonMargin);
	if (!root)
		return vfailed;
	SetRoot(root);

	if(Opened())
		Opened()(sys::getSelf<IDocument>(this),name);

	return vok;
}

vresult Document::Open(const String& name,Workspace* workspace)
{
	m_connection.CreateObject(CLSID_Connection);
	m_name = name;
	m_workspace = workspace;

	if (Opening())
		Opening()(sys::getSelf<IDocument>(this),name);

	sys::ServiceInterfacePtr<IBuildService> pIFBuildService(BUILD_SERVICE);
	if (!pIFBuildService)
		return vfailed;
	IObject* root = pIFBuildService->BuildDocument(GetConnection(),name);
	if (!root)
		return vfailed;
	SetRoot(root);

	if(Opened())
		Opened()(sys::getSelf<IDocument>(this),name);

	return vok;
}

vresult Document::Close()
{
	if (Closing())
		Closing()(sys::getSelf<IDocument>(this),m_name);

	while (!m_linkedviews.empty())
	{
		sys::InterfacePtr<IView> pIFView(*m_linkedviews.begin());
		pIFView->Close();
	}

	if (Closed())
		Closed()(sys::getSelf<IDocument>(this),m_name);

	return vok;
}

vresult Document::Save(const String& name)
{
	if (Saving())
		Saving()(sys::getSelf<IDocument>(this),name);

	m_workspace->UpdateDocumentName(name);
	m_name = name;

	if (Saved())
		Saved()(sys::getSelf<IDocument>(this),name);

	return vok;
}

IWorkspace* Document::GetWorkspace() const
{
	return m_workspace;
}

bool  Document::IsNew() const
{
	int i = _wtoi(m_name.c_str());	
	return i>0;
}

IConnection* Document::GetConnection() const
{
	return sys::InterfacePtr<IConnection>(m_connection);
}

void Document::SetRoot(IObject* root)
{
	m_root = root;
}

IObject* Document::GetRoot() const
{
	return m_root;
}

void Document::UpdateAllViews(IView* activeView)
{
	ViewList::iterator itbegin = m_linkedviews.begin();
	ViewList::iterator itend = m_linkedviews.end();
	for (; itbegin != itend; ++itbegin)
	{
		View* view = (View*)(*itbegin);
		view->Update(activeView);
	}
}

void Document::SetName(const String& name)
{
	m_name = name;
}

const String& Document::GetName() const
{
	return m_name;
}

void Document::AddView(IView* view)
{
	m_linkedviews.push_back(view);
}

void Document::RemoveView(IView* view)
{
	ViewList::iterator itfind = std::find(m_linkedviews.begin(),m_linkedviews.end(),view);
	if (itfind != m_linkedviews.end())
		m_linkedviews.erase(itfind);
}